﻿using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using ZoneLineNew.Controls;
using ZoneLineNew.Core.EventArgs;
using ZoneLineNew.Models;
using ZoneLineNew.Models.Package;
using ZoneLineNew.Models.PrintResult;
using ZoneLineNew.Services.DB;
using ZoneLineNew.Services.Message;
using ZoneLineNew.ViewModelBase;

namespace ZoneLineNew.ViewModels {

    public class ProductReplacViewModel : NavigationViewModel {

        public ProductReplacViewModel(
            IRegionManager regionManager, 
            IDialogService dialog, 
            IMessageService messageBox, 
            IEventAggregator eventAggregator, 
            IDbOperate<IFreeSqlMainContext> dbOperate) 
            : base(regionManager, dialog, messageBox, eventAggregator, dbOperate) {

           
        }

        #region Props

        private string _oldProductCode;
     
        public string OldProductCode {
            get { return _oldProductCode; }
            set { _oldProductCode = value; base.RaisePropertyChanged(); }
        }

        private string _newProductCode;

        public string NewProductCode {
            get { return _newProductCode; }
            set { _newProductCode = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<PackageResult> _packageResults = new ObservableCollection<PackageResult>();

        public ObservableCollection<PackageResult> PackageResults {
            get { return _packageResults; }
            set { _packageResults = value; base.RaisePropertyChanged(); }
        }

        private PackageResult _targetPackagePiece;

        public PackageResult TargetPackagePiece {
            get { return _targetPackagePiece; }
            set { _targetPackagePiece = value; base.RaisePropertyChanged(); }
        }

        private bool _isBoxCode;

        public bool IsBoxCode {
            get { return _isBoxCode; }
            set { _isBoxCode = value; base.RaisePropertyChanged(); }
        }

        private bool _isOldCode;

        public bool IsOldCode {
            get { return _isOldCode; }
            set { _isOldCode = value; base.RaisePropertyChanged(); }
        }

        private bool _isNewCode = true;

        public bool IsNewCode {
            get { return _isNewCode; }
            set { _isNewCode = value; base.RaisePropertyChanged(); }
        }

        private string _searchCode;

        public string SearchCode {
            get { return _searchCode; }
            set { _searchCode = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<ReplaceRecordModel> _replaceRecords = new ObservableCollection<ReplaceRecordModel>();

        public ObservableCollection<ReplaceRecordModel> ReplaceRecords {
            get { return _replaceRecords; }
            set { _replaceRecords = value; base.RaisePropertyChanged(); }
        }
        #endregion

        #region Commands
        public DelegateCommand SearchCommand => new DelegateCommand(() => {
            PackageResults.Clear();
            if (string.IsNullOrEmpty(OldProductCode)) {
                return;
            }
            var packagePieces = _mainDbOperate.GetModelList<PackageResult>(p => p.Code == OldProductCode);
            PackageResults.AddRange(packagePieces);
        });

        public DelegateCommand<PackageResult> ReplaceCommand => new DelegateCommand<PackageResult>((rhs) => ReplacePiece(rhs));

        public DelegateCommand SearchReplaceRecordCmd => new DelegateCommand(() => {
            ReplaceRecords.Clear();
            var list = new List<ReplaceRecordModel>();
            try {
                if (IsBoxCode) {
                    list = _mainDbOperate.GetModelList<ReplaceRecordModel>(p => p.BoxCode == SearchCode);
                } else if (IsNewCode) {
                    list = _mainDbOperate.GetModelList<ReplaceRecordModel>(p => p.NewCode == SearchCode);
                } else if (IsOldCode) {
                    list = _mainDbOperate.GetModelList<ReplaceRecordModel>(p => p.OldCode == SearchCode);
                }
              
            } catch (Exception ex) {
                _message.Error(ex.Message);
            }
            ReplaceRecords.AddRange(list);
        });
        
        #endregion

        protected override void OnViewLoaded() {

            //OldProductCode = "LAA-29150024/5MT/25218/2521850159/M00";
            
            _eventAggregator.GetEvent<PubSubEventArgs>().Subscribe(GetScanBarCode);
            //base.OnViewLoaded();
        }


        private void ReplacePiece(PackageResult targetPackagePiece) {

            if (targetPackagePiece == null) {
                _message.Warning("请先选中要替换的产品!");
                return;
            }
            var confirm = _message.Ask("确认是否更换该产品？");
            if (confirm != System.Windows.MessageBoxResult.OK) {
                return;
            }

            try {
                var replacedFlag = "_replaced";
                var newPiece = _mainDbOperate.GetModel<AbsPrintResult>(p => p.Code == NewProductCode);
                if (newPiece == null) {
                    _message.Error("新输入标签码未查询到该产品！");
                    return;
                }

                var newPieceTemp = _mainDbOperate.GetModel<PackageResult>(p => p.Code == NewProductCode);
                if (newPieceTemp != null) {
                    _message.Error($"新产品已经在其他箱中被装箱，箱号：{newPieceTemp.BoxCode}！");
                    return;
                }

                if (string.IsNullOrEmpty(targetPackagePiece.BoxCode)) {
                    _message.Error("旧产品还未装箱，不能替换！");
                    return;
                }

                if (targetPackagePiece.BoxCode.EndsWith("_replaced")) {
                    _message.Error("旧产品已经从箱中被取出！");
                    return;
                }

                if (newPiece.ProductID > 0 && targetPackagePiece.ProductID > 0 && newPiece.ProductID != targetPackagePiece.ProductID) {
                    _message.Error("非同一款产品，请确认!");
                    return;
                }

                if (newPiece.Model != "" && targetPackagePiece.Model != "" && newPiece.Model != targetPackagePiece.Model) {
                    _message.Error("非同一款产品型号，请确认!");
                    return;
                }

                if (newPiece.LeftRight != targetPackagePiece.LeftRight) {
                    _message.Error("新产品和旧产品的左右型号不一样，请确认!");
                    return;
                }

                var newModelStr = JsonConvert.SerializeObject(newPiece);
                var packageResultNew = JsonConvert.DeserializeObject<PackageResult>(newModelStr);
                packageResultNew.BoxCode = targetPackagePiece.BoxCode;
                packageResultNew.PackageTime = DateTime.Now;

                _mainDbOperate.AddModel<PackageResult>(packageResultNew);
                targetPackagePiece.BoxCode = targetPackagePiece.BoxCode + replacedFlag;
                _mainDbOperate.DeleteModel<PackageResult>(p => p.Id == targetPackagePiece.Id);

                var replaceRecord = new ReplaceRecordModel();
                replaceRecord.BoxCode = targetPackagePiece.BoxCode;
                replaceRecord.OldCode = targetPackagePiece.Code;
                replaceRecord.NewCode = newPiece.Code;
                replaceRecord.CreateTime = DateTime.Now;
                _mainDbOperate.AddModel(replaceRecord);

                _message.GrowSuccess("产品已经替换完成，请对新产品进行装箱！");

            } catch (Exception ex) {
                _message.Error(ex.Message);
            }
        }

        public override void OnNavigatedFrom(NavigationContext navigationContext) {
            _eventAggregator.GetEvent<PubSubEventArgs>().Unsubscribe(GetScanBarCode);
            //base.OnNavigatedFrom(navigationContext);
        }

        private void GetScanBarCode(MessageData messageData) {
            if (messageData.Code == NonClientAreaControl._scanCode && messageData.Parameters.ContainsKey("Content")) {
                string str = messageData.Parameters.GetValue<string>("Content");
                if (string.IsNullOrEmpty(this.OldProductCode)) {
                    this.OldProductCode = str;
                } else if (string.IsNullOrEmpty(this.NewProductCode)) {
                    this.NewProductCode = str;
                }
                this.SearchCode = str;
            }
        }

    }
}
